<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {
  NButton,
  useMessage,
  useThemeVars,
  NSpin,
  NScrollbar,
  NTree,
  type TreeOption,
  type FormRules,
  type FormInst,
  NForm,
  NFormItem,
  NInput,
  NTreeSelect,
  NRadioGroup,
  NRadioButton
} from 'naive-ui'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
import type { DicTreeModel, DicModel } from '@/api/dic'
import { DicType } from '@/enums/system'

const message = useMessage()
const primaryColor = useThemeVars().value.primaryColorHover
const dicLoading = ref(false)
const infoLoading = ref(false)
const formRef = ref<FormInst | null>(null)
const activeId = ref<number | null>(null)
const dicOptions = ref<DicTreeModel[]>([])
const isEdit = ref(false)
const updateLoading = ref(false)
const form = ref<DicModel | null>(null)
const nodeProps = ({ option }: { option: TreeOption }) => {
  return {
    onClick() {
      activeId.value = option.id as number
      queryNodeInfo()
    }
  }
}
const formRules: FormRules = {
  dicName: {
    required: true,
    trigger: ['blur'],
    message: '名称不能为空'
  },
  orderIndex: {
    required: true,
    trigger: ['blur'],
    type: 'number',
    message: '序号码不能为空'
  }
}

// 获取字典列表
const firstExpandedKey = ref<number[]>([])
const queryMenuOptions = async () => {
  infoLoading.value = true
  const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
    module: 'dic',
    api: 'getTree'
  })
  infoLoading.value = false

  if (error) return message.error(error.message)
  if (res.code !== 0) return message.error(res.msg)
  dicOptions.value = res.data
  firstExpandedKey.value = [res.data[0]?.id]
}

// 获取字典详情
const queryNodeInfo = async () => {
  isEdit.value = false
  dicLoading.value = true
  infoLoading.value = true
  const [error, res] = await sendRequest<HttpResponse<DicModel>>({
    module: 'dic',
    api: 'info',
    uri: {
      id: activeId.value as unknown as string
    }
  })
  dicLoading.value = false
  infoLoading.value = false

  if (error) return message.error(error.message)
  if (res.code !== 0) return message.error(res.msg)
  form.value = res.data
  formRef.value?.restoreValidation()
}

const submit = async () => {
  formRef.value?.validate(async (err) => {
    if (err) return

    updateLoading.value = true
    const [error, res] = await sendRequest({
      module: 'dic',
      api: 'update',
      override: {
        data: form.value
      }
    })
    updateLoading.value = false

    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
    message.success(res.msg)
    queryMenuOptions()
    queryNodeInfo()
  })
}

onMounted(async () => {
  queryMenuOptions()
})
</script>

<template>
  <div class="feature">
    <div class="card edit">
      <div class="card__title">数据字典</div>
      <NSpin
        :show="infoLoading"
        class="card__spin"
      >
        <NScrollbar>
          <NTree
            :node-props="nodeProps"
            :data="dicOptions"
            :default-expanded-keys="firstExpandedKey"
            key-field="id"
            label-field="name"
            block-line
          />
        </NScrollbar>
      </NSpin>
    </div>
    <div
      class="card edit"
      v-if="form"
    >
      <div class="card__title">详细信息</div>
      <NSpin
        :show="dicLoading"
        class="card__spin"
      >
        <NScrollbar style="height: calc(100% - 60px)">
          <NForm
            :disabled="!isEdit"
            :model="form"
            :rules="formRules"
            ref="formRef"
            label-placement="left"
            label-width="100"
            size="small"
            style="padding: 15px"
          >
            <NFormItem
              label="上级字典编码"
              path="parentCode"
            >
              <NTreeSelect
                disabled
                v-model:value="form.parentCode"
                :options="dicOptions"
                size="small"
                :placeholder="form.parentCode === 'ROOT' ? 'ROOT' : '请选择'"
                key-field="code"
                label-field="code"
              />
            </NFormItem>
            <NFormItem
              label="字典编码"
              path="dicCode"
            >
              <NInput
                v-model:value="form.dicCode"
                disabled
              />
            </NFormItem>
            <NFormItem
              label="字典名称"
              path="dicName"
            >
              <NInput v-model:value="form.dicName" />
            </NFormItem>
            <NFormItem
              label="排序码"
              path="orderIndex"
            >
              <NInput v-model:value="form.orderIndex" />
            </NFormItem>
            <NFormItem
              label="字典描述"
              path="describe"
            >
              <NInput
                v-model:value="form.describe"
                type="textarea"
              />
            </NFormItem>
            <NFormItem
              label="字典类型"
              path="dicType"
            >
              <NRadioGroup v-model:value="form.dicType">
                <NRadioButton
                  :value="DicType.System"
                  label="系统级"
                />
                <NRadioButton
                  :value="DicType.Custom"
                  label="自定义"
                />
                <NRadioButton
                  :value="DicType.Common"
                  label="通用级"
                />
              </NRadioGroup>
            </NFormItem>
            <NFormItem
              label="状态"
              path="dicStatus"
            >
              <NRadioGroup v-model:value="form.dicStatus">
                <NRadioButton
                  :value="1"
                  label="正常"
                />
                <NRadioButton
                  :value="0"
                  label="禁用"
                />
              </NRadioGroup>
            </NFormItem>
          </NForm>
        </NScrollbar>

        <NButton
          v-if="!isEdit"
          type="primary"
          round
          :disabled="dicLoading"
          style="margin: 13px 15px"
          @click="isEdit = true"
        >
          修改
        </NButton>
        <NButton
          v-else
          type="primary"
          round
          :loading="updateLoading"
          :disabled="updateLoading"
          style="margin: 13px 15px"
          @click="submit"
        >
          保存
        </NButton>
      </NSpin>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.feature {
  display: flex;
  gap: 0 30px;
  width: 100%;
  height: 100%;

  .card {
    height: 100%;
    width: 30%;
    min-width: 400px;

    &__title {
      display: flex;
      align-items: center;
      height: 40px;
      padding: 0 1em;
      font-size: 18px;
      font-weight: 600;
      color: #fff;
      background-color: v-bind(primaryColor);
      border-radius: 3px 3px 0 0;
    }

    &__spin {
      height: calc(100% - 40px);
      border: 1px solid #d1d8e0;
      border-top: none;
      border-radius: 0 0 3px 3px;

      & :deep(.n-spin-content) {
        height: 100%;
      }
    }

    &:nth-child(2) {
      flex: 1;
    }
  }
}
</style>
